/*************************************************************************
 * 		update_firmware.c
 *  Created on: 2023.2.21
 *      Author: Lw
 */

#include <admin_firmware/admin_firmware.h>
#include "update_firmware.h"
#include "lzw_decompress.h"
#include "dri_hal_fatfs.h"
#include "dri_hal_can.h"
#include "tele_data_transfer.h"
extern S_tEquipmentStatus g_tEquipmentStatus;      /* 设备的状态信息结构体 */
static void updateFirmwareReset(void);

u8 updateFirmwareInit(void)
{
    u8 emmcInitRes = XST_FAILURE;
    s_FirmwareUpdate.CurPackageSeq = 0;
    s_FirmwareUpdate.CurPackageSN = 0;
    s_FirmwareUpdate.LastPackageSN = 0;
    s_FirmwareUpdate.CompressDataLen = 0;
    s_FirmwareUpdate.TotalPackageNum = 0;
    s_FirmwareUpdate.TotalCompressDataLen = 0;
    s_FirmwareUpdate.RecvPackageBuffLen = 0;
    s_FirmwareUpdate.RecvCrc16Data = 0;
    s_FirmwareUpdate.EndPackageSeq = 0;
    s_FirmwareUpdate.e_State = INIT;
    g_tEquipmentStatus.ucUpdateStatus = INIT;
    s_FirmwareUpdate.RecvPackageType = 0xffff;
    for(u16 index = 0; index < RECV_PACKAGE_PACKAGE_MAX_NUM ;index++)
    {
        s_FirmwareUpdate.RecvPackageStatus[index] = 0;
    }
    emmcInitRes = emmcInit();//挂载emmc,以及创建文件
	s_FirmwareUpdate.EndPackageSeq = emmcReadParaData(EMMC_ENDPackageSeq_FILE_NAME,2);
    s_FirmwareUpdate.TotalPackageNum = emmcReadParaData(EMMC_TotalPackageNum_FILE_NAME,2);
    s_FirmwareUpdate.TotalCompressDataLen = emmcReadParaData(EMMC_TotalCompressDataLen_FILE_NAME,4);
    emmcInitRes = emmcReadData(EMMC_TotalPackage_STATUS,s_FirmwareUpdate.RecvPackageStatus,RECV_PACKAGE_PACKAGE_MAX_NUM);

	/*判读是否处于接收固件数据中*/
	if(s_FirmwareUpdate.EndPackageSeq != 0 && s_FirmwareUpdate.TotalPackageNum !=0)
	{
	    s_FirmwareUpdate.e_State = RECV_DATA_DURING;
	    g_tEquipmentStatus.updataFwPackageSeq = s_FirmwareUpdate.EndPackageSeq;
	    s_FirmwareUpdate.RecvPackageType = 0;
	}

	return emmcInitRes;
}

/*重置*/
static void updateFirmwareReset(void)
{
    /*删除文件*/
    f_unlink(EMMC_COMPRESS_FILE1_NAME);
    f_unlink(EMMC_COMPRESS_FILE2_NAME);
    f_unlink(EMMC_COMPRESS_FILE3_NAME);
    f_unlink(EMMC_ENDPackageSeq_FILE_NAME);
    f_unlink(EMMC_TotalPackageNum_FILE_NAME);
    f_unlink(EMMC_TotalCompressDataLen_FILE_NAME);
    f_unlink(EMMC_TotalPackage_STATUS);
    /* 标志位复位 */
    s_FirmwareUpdate.CurPackageSeq = 0;
    s_FirmwareUpdate.CurPackageSN = 0;
    s_FirmwareUpdate.LastPackageSN = 0;
    s_FirmwareUpdate.CompressDataLen = 0;
    s_FirmwareUpdate.TotalPackageNum = 0;
    s_FirmwareUpdate.TotalCompressDataLen = 0;
    s_FirmwareUpdate.RecvPackageBuffLen = 0;
    s_FirmwareUpdate.RecvCrc16Data = 0;
    s_FirmwareUpdate.EndPackageSeq = 0;
    s_FirmwareUpdate.e_State = INIT;
    s_FirmwareUpdate.RecvPackageType = 0xffff;
    g_tEquipmentStatus.ucUpdateStatus = INIT;
    g_tEquipmentStatus.updataFwPackageSeq = 0;
    for(u16 index = 0; index < RECV_PACKAGE_PACKAGE_MAX_NUM ;index++)
    {
        s_FirmwareUpdate.RecvPackageStatus[index] = 0;
    }

}


void checkFirmwareData(void)
{
    u8 LackPackNum = 0;
    g_tEquipmentStatus.FwLackPackageNum = 0;
	for(u8 index = 0; index < 90 ; index ++)
	{
		g_tEquipmentStatus.FwLackPackageSeq[index] = 0;
	}

    for(u16 index = 0; index < s_FirmwareUpdate.EndPackageSeq; index++)
    {
        if(s_FirmwareUpdate.RecvPackageStatus[index] != RECV_PACKAGE_CURRENT_DONE)
        {
            if(LackPackNum < 90)
            {
                g_tEquipmentStatus.FwLackPackageSeq[LackPackNum] = (index+1);
                LackPackNum ++;
            }
            g_tEquipmentStatus.FwLackPackageNum ++;
        }
    }
    if(g_tEquipmentStatus.FwLackPackageNum == 0 && s_FirmwareUpdate.EndPackageSeq == s_FirmwareUpdate.TotalPackageNum && s_FirmwareUpdate.e_State == RECV_DATA_DURING)
    {
        s_FirmwareUpdate.e_State = EMMC_DATA_COMPARE;
    }
}

void updateFirmwareProcess(void)
{
	switch(s_FirmwareUpdate.e_State)
	{
	    case RECV_DATA_TERM:
	        updateFirmwareReset();
	        g_tEquipmentStatus.ucUpdateStatus = RECV_DATA_TERM;
	        s_FirmwareUpdate.e_State = INIT;
	    break;

		case RECV_DATA_DURING:
		    g_tEquipmentStatus.ucUpdateStatus = RECV_DATA_DURING;
		break;

		case WRITE_DATA_DURING:
            /*每接收到1个固件包就往emmc中写入固件数据以及最大包序号的包的包序号*/
            g_tEquipmentStatus.ucUpdateStatus = WRITE_DATA_DURING;
            s_FirmwareUpdate.TotalCompressDataLen += s_FirmwareUpdate.RecvPackageRelaxLen;
            if((emmcWriteData(EMMC_COMPRESS_FILE1_NAME, s_FirmwareUpdate.CompressPackRelax, s_FirmwareUpdate.RecvPackageRelaxLen, ((s_FirmwareUpdate.CurPackageSeqRelax - 1) * 222)) == FR_OK)
            && (emmcWriteData(EMMC_COMPRESS_FILE2_NAME, s_FirmwareUpdate.CompressPackRelax, s_FirmwareUpdate.RecvPackageRelaxLen, ((s_FirmwareUpdate.CurPackageSeqRelax - 1) * 222)) == FR_OK)
            && (emmcWriteData(EMMC_COMPRESS_FILE3_NAME, s_FirmwareUpdate.CompressPackRelax, s_FirmwareUpdate.RecvPackageRelaxLen, ((s_FirmwareUpdate.CurPackageSeqRelax - 1) * 222)) == FR_OK)
            && (emmcWriteParaData(EMMC_ENDPackageSeq_FILE_NAME, s_FirmwareUpdate.EndPackageSeq, 2) == FR_OK)
            && (emmcWriteParaData(EMMC_TotalCompressDataLen_FILE_NAME, s_FirmwareUpdate.TotalCompressDataLen, 4) == FR_OK))
            {
                g_tEquipmentStatus.updataFwPackageSeq = s_FirmwareUpdate.EndPackageSeq;
                s_FirmwareUpdate.e_State = RECV_DATA_DURING;
                s_FirmwareUpdate.RecvPackageStatus[s_FirmwareUpdate.CurPackageSeqRelax-1] = RECV_PACKAGE_CURRENT_DONE;
                if((emmcWriteData(EMMC_TotalPackage_STATUS, &(s_FirmwareUpdate.RecvPackageStatus[s_FirmwareUpdate.CurPackageSeqRelax - 1]), 1, s_FirmwareUpdate.CurPackageSeqRelax - 1) != FR_OK)){
                	 s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
                }
                if(s_FirmwareUpdate.CurPackageSeq == FIRMWARE_FIRSTSEQ_PACKAGE)
				{
					if(emmcWriteParaData(EMMC_TotalPackageNum_FILE_NAME, s_FirmwareUpdate.TotalPackageNum, 2) != FR_OK){
					    s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
					}
                }
            } else {
                s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
            }
		break;

        case EMMC_WR_DATA_FAIL:
            g_tEquipmentStatus.ucUpdateStatus = EMMC_WR_DATA_FAIL;
        break;

		case EMMC_DATA_COMPARE:
		    g_tEquipmentStatus.ucUpdateStatus = EMMC_DATA_COMPARE;
            if(emmcReadData(EMMC_COMPRESS_FILE1_NAME, s_FirmwareUpdate.EmmcCompareData1, s_FirmwareUpdate.TotalCompressDataLen) == FR_OK
                && emmcReadData(EMMC_COMPRESS_FILE2_NAME, s_FirmwareUpdate.EmmcCompareData2, s_FirmwareUpdate.TotalCompressDataLen) == FR_OK
                && emmcReadData(EMMC_COMPRESS_FILE3_NAME, s_FirmwareUpdate.EmmcCompareData3, s_FirmwareUpdate.TotalCompressDataLen) == FR_OK)
		    {
		        /*mem_cmp函数返回0时表示数据相等*/
		        if(mem_cmp(s_FirmwareUpdate.EmmcCompareData1,s_FirmwareUpdate.EmmcCompareData2,s_FirmwareUpdate.TotalCompressDataLen) == 0)
		        {
		            if(emmcWriteData(EMMC_COMPRESS_FILE_NAME, s_FirmwareUpdate.EmmcCompareData1, s_FirmwareUpdate.TotalCompressDataLen,0) == FR_OK)
		            {
		                s_FirmwareUpdate.e_State = EMMC_DATA_COMPARE_SUCCEED;
		            }
		            else
		            {
		                s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
		            }
		        }
		        else if(mem_cmp(s_FirmwareUpdate.EmmcCompareData2,s_FirmwareUpdate.EmmcCompareData3,s_FirmwareUpdate.TotalCompressDataLen) == 0)
		        {
                    if(emmcWriteData(EMMC_COMPRESS_FILE_NAME, s_FirmwareUpdate.EmmcCompareData2, s_FirmwareUpdate.TotalCompressDataLen, 0) == FR_OK)
                    {
                        s_FirmwareUpdate.e_State = EMMC_DATA_COMPARE_SUCCEED;
                    }
                    else
                    {
                        s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
                    }
		        }
                else if(mem_cmp(s_FirmwareUpdate.EmmcCompareData3,s_FirmwareUpdate.EmmcCompareData1,s_FirmwareUpdate.TotalCompressDataLen) == 0)
                {
                    if(emmcWriteData(EMMC_COMPRESS_FILE_NAME, s_FirmwareUpdate.EmmcCompareData3, s_FirmwareUpdate.TotalCompressDataLen, 0) == FR_OK)
                     {
                         s_FirmwareUpdate.e_State = EMMC_DATA_COMPARE_SUCCEED;
                     }
                     else
                     {
                         s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
                     }
                }
                else
                {
                    s_FirmwareUpdate.e_State = EMMC_DATA_COMPARE_FAIL;
                }
		    }
		    else
		    {
		        s_FirmwareUpdate.e_State = EMMC_WR_DATA_FAIL;
		    }
		break;

        case EMMC_DATA_COMPARE_SUCCEED:
            g_tEquipmentStatus.ucUpdateStatus = EMMC_DATA_COMPARE_SUCCEED;
        break;

		case EMMC_DATA_COMPARE_FAIL:
		    g_tEquipmentStatus.ucUpdateStatus = EMMC_DATA_COMPARE_FAIL;
		break;

		case UNCOMPRESS_DATA://这里运行解压缩，解压缩时间为5秒左右，期间将不会有ttc中断触发，就是说解压缩期间程序将一直在这个状态
		    g_tEquipmentStatus.ucUpdateStatus = UNCOMPRESS_DATA;
		    if(lzw() == 0)
		    {
		        s_FirmwareUpdate.e_State = WRI_SUCCEED;
		    }
		    else
		    {
		        s_FirmwareUpdate.e_State = UNCOMPRESS_DATA_FAIL;
		    }
        break;

		case UNCOMPRESS_DATA_FAIL:
		    g_tEquipmentStatus.ucUpdateStatus = UNCOMPRESS_DATA_FAIL;
		break;

		case PIXEL_MASK_BEGIN:
		    g_tEquipmentStatus.ucUpdateStatus = PIXEL_MASK_BEGIN;
		break;

		case WRI_SUCCEED: //给协fpga发送命令，从emmc中启动程序
			updateFirmwareReset();
			SendChangeEmmcMsg();
            break;

		default :
		break;
	}
}

void updateFirmwareTerm(void)
{
    s_FirmwareUpdate.e_State =  RECV_DATA_TERM ;            //接收固件数据终止
}

void beginUpdateFirmware(void)
{
    if(s_FirmwareUpdate.e_State == EMMC_DATA_COMPARE_SUCCEED)
    {
        s_FirmwareUpdate.e_State =  UNCOMPRESS_DATA ;
    }

}






